﻿using Bll.User;
using ShareCode.Entity.User;
using Infrastructure.Attributes.Ioc;
using Microsoft.AspNetCore.Mvc;
using Infrastructure.Attributes;
using Infrastructure.Util.Helper;
using Infrastructure.Model;
using ShareCode.Dto.User;
using Infrastructure.MyException;

namespace ApiApp.Controllers.User
{
    /// <summary>
    /// by zhouxin
    ///</summary>
    [ApiController]
    [Route("User/[controller]")]
    [Component(ServiceLifetime.Transient)]
    [Auth(1, "Account")]
    public class UserAccountController : BaseContainDateController<UserAccountEntity>
    {
        protected override UserAccountBll? Bll => (UserAccountBll?)base.Bll;

        [Autowired]
        public UserAccountBll SetBll { set { this._Bll = value; } }


        /// <summary>
        /// 
        /// </summary>
        /// <remarks></remarks>
        /// <param name="height"></param>
        /// <param name="width"></param>
        /// <param name="requestToken"></param>
        /// <returns></returns>
        [HttpGet("validcode/{height}/{width}")]
        [Auth("获取验证码")]
        public FileContentResult ValidCodeAsync(int height, int width, string requestToken = "")
        {
            string code;
            MemoryStream ms;

            while (true)
            {
                (code, ms) = VCodeHelper.GenVCode(width, height, 5);
                if (!(RedisHelper.GetObject(RedisDbBusiness.Core)?.KeyExists(RedisKeyPrefix.ValidCode + requestToken + code?.ToLower())??false))
                {
                    RedisHelper.GetObject(RedisDbBusiness.Core)?
                        .StringSet(RedisKeyPrefix.ValidCode + requestToken + code?.ToLower(), code?.ToLower()??"", new TimeSpan(0, 1, 0));
                    break;
                }
            }

            return File(ms.ToArray(), "image/gif");
        }

        [HttpPost("LoginByNameAndPsw")]
        [Auth("使用用户名密码登录")]
        public Task<JsonResult> LoginByNameAndPsw([FromBody] LoginByNameAndPswResqestDto loginByNameAndPsw)
        {
            ShowUserLogicException exception = new ShowUserLogicException("注册信息验证不通过");

            if (string.IsNullOrEmpty(loginByNameAndPsw.Verification)) { exception.AddSonMessage("Verification", "验证码无效"); }
            else if (!(RedisHelper.GetObject(RedisDbBusiness.Core)?.KeyExists(RedisKeyPrefix.ValidCode + loginByNameAndPsw.RequestToken + loginByNameAndPsw.Verification.ToLower())??false))
            {
                exception.AddSonMessage("Verification", "验证码无效");
            }

            if (string.IsNullOrEmpty(loginByNameAndPsw.UserName)) { exception.AddSonMessage("UserName", "用户名无效"); }
            if (string.IsNullOrEmpty(loginByNameAndPsw.Password)) { exception.AddSonMessage("Password", "密码无效"); }

            if (!(RedisHelper.GetObject(RedisDbBusiness.Core)?.KeyExists(RedisKeyPrefix.ValidCode + loginByNameAndPsw.RequestToken + loginByNameAndPsw.Verification))??false)
            {
                exception.AddSonMessage("Verification", "验证码无效");
            }

            if (exception.SonErrs.Count > 0)
            {
                return Task.FromResult(Err(exception));
            }

            return OkkAsync(Bll!.LoginByNameAndPswAsync(loginByNameAndPsw));
        }


        [HttpPost("Register")]
        [Auth("用户注册")]
        public Task<JsonResult> Register([FromBody] UserRegisterDto registerDto)
        {
            ShowUserLogicException exception = new ShowUserLogicException("注册信息验证不通过");

            if (string.IsNullOrEmpty(registerDto.Verification)) { exception.AddSonMessage("Verification", "验证码无效"); }
            if (string.IsNullOrEmpty(registerDto.UserName)) { exception.AddSonMessage("UserName", "用户名无效"); }
            if (string.IsNullOrEmpty(registerDto.Psw)) { exception.AddSonMessage("Psw", "密码无效"); }

            if (!(RedisHelper.GetObject(RedisDbBusiness.Core)?.KeyExists(RedisKeyPrefix.ValidCode + registerDto.RequestToken + registerDto.Verification))??false)
            {
                exception.AddSonMessage("Verification", "验证码无效");
            }

            if (exception.SonErrs.Count > 0)
            {
                return Task.FromResult(Err(exception));
            }

            return OkkAsync(Bll!.Register(registerDto));
        }

    }
}
